import re
from typing import Generic, TypeVar
import json
from simpleutil.json import (
    json_obj_configuration,
    json_str_configuration,
    convert_json_object,
)

T = TypeVar("T")


def singleton(cls):
    instances = {}

    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance


class Result:
    pass


class ConsoleResult:
    def print(self):
        pass


class ListResult(list[T], ConsoleResult, Generic[T]):
    def __init__(self, *args: T):
        super().__init__(args)

    def print(self):
        for item in self:
            print(item)


class ToolClass:
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        # 确保子类在实例化时自动调用父类的 __init__
        original_init = cls.__init__

        def new_init(self, *args, **kwargs):
            ToolClass.__init__(self)
            original_init(self, *args, **kwargs)

        cls.__init__ = new_init

    def __init__(
        self,
        json_obj_config: dict = json_obj_configuration(),
        json_str_config: dict = json_str_configuration(),
    ):
        self.__json_obj_config__ = json_obj_config
        self.__json_str_config__ = json_str_config

    def to_json_obj(self) -> dict:
        return convert_json_object(self, **self.__json_obj_config__)

    def to_json_str(self) -> str:
        json_obj = self.to_json_obj()
        json_str = json.dumps(json_obj, **self.__json_str_config__["dumps_config"])
        config = self.__json_str_config__["common_config"]
        if config["kv_spaces_num"] != -1:
            json_str = re.sub(r":\s+", ":" + " " * config["kv_spaces_num"], json_str)
        return json_str

    def __str__(self) -> str:
        return json.dumps(self.to_json_obj(), **self.__json_str_config__)
